<?php

namespace app\admin\behaviour;

use app\admin\exception\AuthException;
use app\common\CacheKey;
use think\Cache;
use think\Config;
use think\Db;
use think\Loader;
use think\Request;
use Firebase\JWT\JWT;
use traits\controller\Jump;

Loader::import('controller/Jump', TRAIT_PATH, EXT);


class Auth{
    use Jump;

    protected $admin;

    protected $whiteList = [
        "admin/login/login"
    ];


    public function run(Request $request){
        $module = $request->module();
        if($module != "admin") return;

        $path = strtolower($request->module().'/'.$request->controller().'/'.$request->action());
        if(in_array($path,$this->whiteList)) return;

        $jwtKey = Config::get("jwt_key");
        $token = $request->header("Authorization");
        try{
            $payload = JWT::decode($token,$jwtKey, array('HS256'));
            if($payload){
                //检测登录时间 是否过期

                if($payload->exp < time()){
                    throw new AuthException("登录过期");
                }
                $this->admin = Cache::get(CacheKey::ADMIN."#".$payload->id); //配置的名称应该统一，不然怕出错
                if(empty($this->admin)){

                    $this->collectAdminInfo($payload->id,$payload->exp);
                }

                $this->checkPermission($request->controller(),$request->action());
                $request->header("adminId",$payload->id);
            }else{
                throw new AuthException("没有登录");
            }

        }catch (\Exception $e){
            $this->error($e->getMessage());
        }
    }

    protected function collectAdminInfo($id,$expireTime){
        $this->admin =Db::table("admin")->where(['id'=>$id])->find();
        if(empty($admin['role_ids'])){
            $this->admin['permissions'] = [];
        }else{
            $this->admin['permissions'] = $this->getPermission($this->admin['role_ids']);
        }
        Cache::set(CacheKey::ADMIN."#".$this->admin['id'],$this->admin,($expireTime - time())); //跟登录的时间有效期一样长
    }

    protected  function  getPermission($roleIds){
        $permissionStrings= Db::table("role")->whereIn('id',$roleIds)->column("permission_str");
        $permissions = [];
        foreach($permissionStrings as $val){
            $permission = explode(",",$val);
            $permissions = array_merge($permissions,$permission);
        }
        return $permissions;
    }

    protected function  checkPermission($controller,$action){
        $controllerAndAction = $controller."::".$action;
        if(!in_array($controllerAndAction,$this->admin['permissions']) && $this->admin['is_super'] != 1){
            throw new AuthException("没有权限");
        }
    }

}